基本介绍

Prettier 是一个代码风格修正工具。官网:https://prettier.io/

代码风格是所有程序员都要遇到的问题,不管是团队协作还是个人:

代码风格太主观了,根本无法让谁信服谁,也没有绝对的是非对错。有没有办法自动格式化,统一代码风格?

Prettier 是一个流行的代码格式化工具,它可以自动调整代码的样式,使其更具可读性和一致性。它支持多种编程语言,包括 JavaScript、TypeScript、HTML、CSS、SCSS、GraphQL、JSON、Markdown 等。

![[2023-07-12-080354.jpg|500]]

Prettier 的核心特点包括:

其实在很早之前已经有人开始研究哪种方式来格式化长文本是最好的(Prettier Printer),比如 Philip Wadler 在 《A prettier printer》这里给出了一些自动格式化换行的理论依据:

A good pretty printer must strike a balance between ease of use, flexibility of format, and optimality of output.

Prettier 的作者 James 在这篇论文基础上再完善了一些代码风格规则,最终成为了 Prettier 格式化代码的最终方案。比如像下面的链式调用,Prettier 输出的就比原来论文描述的要好看一些:

// 原版 "A prettier printer" 的实现
hello().then(() => {
  something()
}).catch(console.error)


// Prettier 的实现
hello()
  .then(() => {
    something()
  })
  .catch(console.error)

工作原理

Prettier 是如何能够做到代码的格式化?

首先,Prettier 会把代码转换成 [[002.抽象语法树|AST(抽象语法树)]],这里用到的是一个叫 Recast 的库,而 Recast 实际上也用了 Esprima 来解析 ES6。

^02e5fb

所以无论之前的代码怎么乱、怎么屎,Prettier 都抹掉之前的所有样式,抽成最本质的语法树。然后再用 Prettier 的代码风格规则来输出格式化后的代码。

Prettier 能够支持的格式化语言是多种多样的,并非仅仅只为 JS 服务。理论上来讲,只要把一门语言的代码抽象为语法树,然后再有对应的格式化规则,那么无论什么语言都是可以的。

Prettier 官方以及社区就提供了一些插件,通过使用插件,可以添加对新语言和文件类型的支持,让 Prettier 格式化更多种类的代码。Prettier 插件通常是单独的 npm 包,需要安装它们作为项目的依赖。插件的名称通常遵循 prettier-plugin-* 的命名规范。安装插件后,Prettier 会自动发现并使用它们。

以下是一些常见的 Prettier 插件示例:

Opinionated VS. Unopinionated

另外,Prettier 的官方文档里一直在强调自己是一个 Opinionated(固执己见的)的工具,这里想展开聊聊 Opinionated。

其实不仅 Prettier,我们日常使用的一些库和框架都会标明自己是 opinionated 还是 unopinionated:

![[2023-07-12-080447.jpg]]

![[Pasted image 20240321123822.png]]

按照框架/库的 opinionated 还是 unopinionated 思路来使用它们非常重要:

Prettier 属于 Opinionated 哲学,这意味着它提供的代码风格已经是最优的,不希望使用者做太多自定义的内容,而应该相信 Prettier 已经服务到位了。

快速上手

新建一个项目,使用 pnpm init 进行初始化,安装 prettier

pnpm add --save-dev --save-exact prettier

package.json 里面添加命令行脚本:

"scripts": {
    // ...
    "format": "prettier --write ./src"
},

之后就可以使用 pnpm format 这条命令来进行格式化代码操作。

也可以通过安装 VSCode 插件的方式来使用 Prettier。使用脚本命令和使用 VSCode 插件两者之间的差别如下:

如果想要自定义规则,可以在项目根目录下面创建一个 .prettierrc 文件,之后使用对象的形式写入自定义规则即可:

{
  "singleQuote": true,
  "semi": false,
  "printWidth": 120,
  "useTabs": false,
  "tabWidth": 2,
  "bracketSpacing": true,
  "trailingComma": "all",
  "arrowParens": "avoid"
}

详见 [[002.格式化规则|Prettier 格式化规则]]